<template>
  <div class="ttt-tooltip" :class="[position]" :style="tooltipStyle">
    <slot
    ><span style="white-space: pre-line">{{ titleValue }}</span></slot
    >
    <div class="ttt-tooltip-trip" :style="tripStyle"></div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, ref } from 'vue'
import type { PropType, CSSProperties } from 'vue'

export type TooltipPosition =
  | 'topLeft'
  | 'top'
  | 'topRight'
  | 'rightTop'
  | 'right'
  | 'rightBottom'
  | 'bottomLeft'
  | 'bottom'
  | 'bottomRight'
  | 'leftTop'
  | 'left'
  | 'leftBottom'

export interface TooltipProps {
  title: string | number
  position: TooltipPosition
  width: string | number
  color: string
  plain: boolean
}

export const TooltipPositionArr = [
  'topLeft',
  'top',
  'topRight',
  'rightTop',
  'right',
  'rightBottom',
  'bottomLeft',
  'bottom',
  'bottomRight',
  'leftTop',
  'left',
  'leftBottom'
]

export default defineComponent({
  name: 'fxTooltip',
  props: {
    // 提示文字
    title: {
      type: [String, Number] as PropType<string | number>,
      default: '',
      required: true
    },
    // 提示方向
    position: {
      type: String as PropType<TooltipPosition>,
      default: 'top',
      validator(val: string): boolean {
        return TooltipPositionArr.includes(val)
      }
    },
    width: {
      type: [String, Number] as PropType<string | number>,
      default: 220
    },
    color: {
      type: String as PropType<string>,
      default: null
    },
    plain: {
      type: Boolean as PropType<boolean>,
      default: false
    }
  },
  setup(props: TooltipProps) {
    const titleValue = ref<string | number>(props.title)

    const tooltipStyle = computed<CSSProperties>((): CSSProperties => {
      return {
        maxWidth: `${props.width}rem`,
        backgroundColor: !props.plain ? props.color : '#fff',
        borderColor: props.color,
        color: props.plain ? props.color || '#333' : '#fff'
      }
    })

    const tripStyle = computed<CSSProperties>((): CSSProperties => {
      return {
        backgroundColor: !props.plain ? props.color : '#fff',
        borderColor: props.color
      }
    })

    const setTitleValue = (val: string | number): void => {
      titleValue.value = val
    }

    return {
      tripStyle,
      titleValue,
      tooltipStyle,
      setTitleValue
    }
  }
})
</script>

<style scoped lang="scss">
@keyframes ttt-animation-tooltip {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.ttt-tooltip {
  position: fixed;
  z-index: 1000;
  height: fit-content;
  padding: 5rem 15rem;
  background-color: #303133;
  color: #fff;
  border-radius: var(--base-border-radius);
  border: 1rem solid #303133;
  animation: ttt-animation-tooltip 0.3s ease-in-out;

  &.topLeft,
  &.top,
  &.topRight {
    > .ttt-tooltip-trip {
      bottom: -4rem;
      border-top-color: transparent !important;
      border-left-color: transparent !important;
    }
  }

  &.topLeft {
    transform: translateY(-100%);

    > .ttt-tooltip-trip {
      left: 15rem;
    }
  }

  &.top {
    transform: translateX(-50%) translateY(-100%);

    > .ttt-tooltip-trip {
      left: 50%;
      transform: translateX(-50%) rotate(45deg);
    }
  }

  &.topRight {
    transform: translateX(-100%) translateY(-100%);

    > .ttt-tooltip-trip {
      right: 15rem;
    }
  }

  &.rightTop,
  &.right,
  &.rightBottom {
    > .ttt-tooltip-trip {
      left: -4rem;
      border-top-color: transparent !important;
      border-right-color: transparent !important;
    }
  }

  &.rightTop {
    > .ttt-tooltip-trip {
      top: 5rem + 3;
    }
  }

  &.right {
    transform: translateY(-50%);

    > .ttt-tooltip-trip {
      top: 50%;
      transform: translateY(-50%) rotate(45deg);
    }
  }

  &.rightBottom {
    transform: translateY(-100%);

    > .ttt-tooltip-trip {
      bottom: 5rem + 3;
    }
  }

  &.leftTop,
  &.left,
  &.leftBottom {
    > .ttt-tooltip-trip {
      right: -4rem;
      border-bottom-color: transparent !important;
      border-left-color: transparent !important;
    }
  }

  &.leftTop {
    transform: translateX(-100%);

    > .ttt-tooltip-trip {
      top: 5rem + 3;
    }
  }

  &.left {
    transform: translateX(-100%) translateY(-50%);

    > .ttt-tooltip-trip {
      top: 50%;
      transform: translateY(-50%) rotate(45deg);
    }
  }

  &.leftBottom {
    transform: translateX(-100%) translateY(-100%);

    > .ttt-tooltip-trip {
      bottom: 5rem + 3;
    }
  }

  &.bottomLeft,
  &.bottom,
  &.bottomRight {
    > .ttt-tooltip-trip {
      top: -4rem;
      border-bottom-color: transparent !important;
      border-right-color: transparent !important;
    }
  }

  &.bottomLeft {
    > .ttt-tooltip-trip {
      left: 15rem;
    }
  }

  &.bottom {
    transform: translateX(-50%);

    > .ttt-tooltip-trip {
      left: 50%;
      transform: translateX(-50%) rotate(45deg);
    }
  }

  &.bottomRight {
    transform: translateX(-100%);

    > .ttt-tooltip-trip {
      right: 15rem;
    }
  }

  > .ttt-tooltip-trip {
    width: 6rem;
    height: 6rem;
    border: 1rem solid #303133;
    background-color: #303133;
    position: absolute;
    transform: rotate(45deg);
  }
}
</style>
